Tuto rapide pour la version BETA
--------------------------------

Installation :
--------------

Pour utiliser GBAlib dans un programme, il suffit d'include 'gbaVar.inc' au dbut du
programme, et 'gba.inc'  la fin, comme ceci :

#include "crash82.inc"
#include "gbaVar.inc"

.org START_ADDR
.db "gbaTest",0

	; ton prog

#include "gba.inc"

.end


Le fichier 'gbaVar' contient l'ensemble des constantes utilise par la lib. Si tu ne connais
pas la signification d'une constante, laisse la valeur par dfaut. Le fichier gba.inc
contient tout simplement les routines.


Configurer la fentre
---------------------

La fentre est la portion de l'cran dans laquelle va s'afficher la carte et les sprites.
Par dfaut, la fentre fait la taille de l'cran, mais il est possible de changer cela :
- la constante screenWidth indique la largeur de la fentre en nombre de tiles (chaque tile
fait 8x8 pixels)
- la constante screenHeight indique la hauteur de la fentre en nombre de tiles
- screenOffsetY indique la distance, en pixels, entre la haut de l'cran et le haut de la
fentre (ou plus simplement, il s'agit de l'ordonne du point en haut  gauche de la fentre)
- screenOffsetX indique la distance, en octets cette fois, entre le bord gauche de l'cran
et le bord gauche de la fentre (ou plus simplement, il s'agit de l'abscisse su point en haut
 gauche de la fentre)

Attention, il faut avoir	8*screenHeight + screenOffsetY <= 64
et				8*screenWidth + 8*screenOffsetX <= 96
sinon la fentre sort de l'cran, et le programme peut planter...

Remarque : La plupart des routines sont optimises selon les valeurs de ces constantes (un
peu comme des templates). Dans le cas gnral, les routines sont bien plus rapides lorsqu'on
a screenWidth=12 (parce qu'on peut souvent faire des ldir).


backBuffer et frontBuffer :

Ces constantes dsignent les couches successives dont GBAlib a besoin. backBuffer est
l'adresse o va tre stocke la carte. Il ne faut pas modifier les octets de ce buffer.
frontBuffer est l'adresse o la carte est recopie  chaque boucle (voir la routine
gbaRestoreMap), et ou sont affichs les sprites. On peut modifier les octets de ce buffer.


Afficher une carte
-------------------

Une carte est constitu de tiles, portant chacun un numro, et une matrice indiquant la place
des tiles :

tileImg:
.db %00000000		; tile numro 0
.db %00000000
.db %00000000
.db %00000000
.db %00000000
.db %00000000
.db %00000000
.db %00000000

.db %01111110		; tile numro 1
.db %11000011
.db %10000101
.db %10100011
.db %11000101
.db %10100001
.db %11000011
.db %01111110

.db %11111111 		; tile numro 2
.db %11111111
.db %11111111
.db %11111111
.db %11111111
.db %11111111
.db %11111111
.db %11111111

mapData:
.db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
.db 1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0
.db 0,1,0,1,0,1,0,1,0,1,0,1,1,1,1,1
.db 1,0,1,0,1,2,1,0,1,0,1,0,1,0,1,0
.db 0,1,0,1,0,2,0,1,0,1,0,1,1,1,1,1
.db 1,0,1,0,1,2,1,0,1,0,1,0,1,0,1,0
.db 0,1,0,1,0,1,0,1,0,1,0,1,1,1,1,1
.db 1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0
.db 0,1,0,1,0,1,0,1,0,1,0,1,1,1,1,1
.db 1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0
.db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1


On a dans cette exemple une carte de taille 11*16 (on spcifie toujours la hauteur en premier)
qui comporte 3 tiles diffrent.

Il faut tout d'abord indiquer ces donnes  Gba, par l'intermdiaire de variables:
- mapAddr contient l'adresse de la matrice (data)
- tileAddr contient l'adresse des tiles de la carte
- mapHeight contient la hauteur de la carte en tiles
- mapWidth contient la largeur de la carte en tiles

toutes ces variables sont de taille 16bits, mais les valeurs de mapHeight et mapWidth
doivent tre infrieur ou gale  255 (pour permettre des optimisations).

Maintenant que GBA connait les infos sur la carte, on peut demander son affichage avec
la routine gbaInitMap. Celle-ci copie un bout de la carte dans le backBuffer.

Ensuite, il suffit d'appeler la routine gbaRestoreMap pour copier le contenu du backBuffer
dans le frontBuffer, et enfin, si le frontBuffer vaut GRAPH_MEM (ce que je recommande
fortement), appelr CR_GRBCopy (pour copier le contenu de GRAP_MEM dans la mmoire du 
vido-contolleur). Voici  quoi ressemble le prog :

#include "crash82.inc"
#include "gbaVar.inc"

.org START_ADDR
.db "gbaTest",0

	ld hl,tileImg
	ld (tileAddr),hl
	ld hl,mapData
	ld (mapAddr),hl
	ld hl,11
	ld (mapHeight),hl
	ld hl,16
	ld (mapWidth),hl
	call gbaInitMap
	call gbaRestoreMap
	call CR_GRBCopy
Pause:
	call GET_KEY
	cp G_ENTER
	jr nz,Pause
	ret

tileImg:
.db %00000000		; tile numro 0
.db %00000000
.db %00000000
.db %00000000
.db %00000000
.db %00000000
.db %00000000
.db %00000000

.db %01111110		; tile numro 1
.db %11000011
.db %10000101
.db %10100011
.db %11000101
.db %10100001
.db %11000011
.db %01111110

.db %11111111 		; tile numro 2
.db %11111111
.db %11111111
.db %11111111
.db %11111111
.db %11111111
.db %11111111
.db %11111111

mapData:
.db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
.db 1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0
.db 0,1,0,1,0,1,0,1,0,1,0,1,1,1,1,1
.db 1,0,1,0,1,2,1,0,1,0,1,0,1,0,1,0
.db 0,1,0,1,0,2,0,1,0,1,0,1,1,1,1,1
.db 1,0,1,0,1,2,1,0,1,0,1,0,1,0,1,0
.db 0,1,0,1,0,1,0,1,0,1,0,1,1,1,1,1
.db 1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0
.db 0,1,0,1,0,1,0,1,0,1,0,1,1,1,1,1
.db 1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0
.db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1

.end


Comme on peut le voir, c'est la partie en haut  gauche de la carte qui est affiche
dans la fentre par dfaut. On peut changer cela en modifiant les valeurs de scrollY et
scrollX, qui donnent les dfilements vertical et horizontal de la carte, en nombre de tiles.
Par exemple, mettre scrollX  5 avant d'appeler gbaInitMap aura pour effet de 'sauter' les 5
premires colonnes de tiles de la carte (la colonne de '2' sera donc tout  gauche de la
fentre)

scrollX et scrollY sont des variables 16bits, mais doivent tre infrieures  255
(on doit en fait avoir scrollX + screenWidth <= mapWidth et
 scrollY + 8*screenHeight <= mapHeight pour ne pas dpasser les bords de la carte).

Faire un scroll
---------------

Pour faire un scroll vers le bas, vers le haut, vers la gauche ou vers la droite, il suffit
d'appeler les routines gbaScollDown, gbaScrollUp, gbaScrollLeft et gbaScrollRight. C'est
tout !

Si on le scroll s'est rvle impossible, parce qu'on avait dj atteind les bords de la carte,
la routine renvoie le flag 'carry'.

scrollRight:
	call gbaScrollRight
	ret nc
	; on a pas pu faire le scroll
	; traitement...
	ret


Une chose importante  savoir est que ces routines ne redessinent pas intgralement le bout
de carte qui est  l'cran, mais se contentent de scroller celui qui est dans le backBuffer
 et de dessiner les colonnes qui viennent
d'apparatre. C'est pour a qu'il ne faut pas changer les octets dans le backBuffer.


Affichage de sprites
--------------------

Un sprite est un lment de la fentre, gnralement en mouvement, de taille variable (non
ncessairement un multiple de 8). Tous les pixels qui composent le sprite sont cods sur
deux bits :
- un bit de donne pour dfinir s'il est blanc (0) ou noir (1)
- un bit de transparence pour dfinir, dans le cas o le pixel est blanc, s'il est transparent
 (1) ou non (0).

Cette technique est la technique d'affichage avec masque, car on applique sur la fentre
un masque qui va effacer certains pixels avant d'afficher l'image elle-mme.

-->Format des sprites sous GBAlib :

Suppsons que l'on veuille faire un sprite de taille 6*6, un disque par exemple. Puisqu'on
ne peut dfinir que des octets en assembleur, il faut allonger la taille de l'image, en
8*6 :

.db %00110000
.db %01001000
.db %10000100
.db %10000100
.db %01001000
.db %00110000

puis on s'occupe du masque. Pour cela, il suffit de dire que tous les pixels noirs et ceux
 l'intrieur du cercle ne sont pas transparent, et les autres le sont :

.db %11001111
.db %10000111
.db %00000011
.db %00000011
.db %10000111
.db %11001111

Ce n'est pas encore termin. Dans GBAlib, les donnes et le masque sont mlangs : on
spcifie un octet de donnes puis un octet de masque, un octet de donnes, puis un octet
de masque, etc. On obtient ceci :

spriteImg:
.db %00110000,%11001111
.db %01001000,%10000111
.db %10000100,%00000011
.db %10000100,%00000011
.db %01001000,%10000111
.db %00110000,%11001111

Il ne reste plus qu' appeler sous-routine gbaDrawMaskSprite, avec les bons arguments :
- b et c indiquent l'abscisse et l'ordonne (en picels) du sprite par rapport au coin haut gauche
 de la fentre. 
- d et e indiquent la largeur en octets et la hauteur en pixel du sprite. Ici, d=1 et e=6.
- hl indique l'adresse de l'image du sprite. Ici, hl=spriteImg.

Exemple :

#include "crash82.inc"
#include "gbaVar.inc"

.org START_ADDR
.db "gbaSpriteTest",0


	ld hl,Mario_sprite
	ld de,$021c			; d=2, e=28
	ld bc,$1024			; b=16, c=36
	call gbaDrawMaskSprite
	call CR_GRBCopy

Pause:
	call GET_KEY
	cp G_ENTER
	jr nz,Pause
	ret

Mario_sprite:
	.db %11111110,%00000001,%00001111,%11110000 	; n'oubliez pas que les octets
	.db %11111000,%00000110,%00000111,%00001000	; de donnes et les octets
	.db %11110000,%00001000,%00000111,%00001000	; du masque sont mlangs !
	.db %11100000,%00010001,%00000011,%11111100
	.db %11000000,%00100111,%00000001,%11111110
	.db %10000000,%01001111,%00000001,%11111110
	.db %10000000,%01001100,%00000011,%00001100
	.db %10000000,%01011000,%00000011,%10100000
	.db %00000000,%11011000,%00000011,%10100100
	.db %00000000,%11011100,%00000011,%00000100
	.db %10000000,%01001001,%00000011,%00000100
	.db %10000000,%01100011,%00000001,%11111110
	.db %11000000,%00110000,%00000011,%11111100
	.db %11100000,%00011100,%00000111,%00001000
	.db %11110000,%00001111,%00001111,%11110000
	.db %11100000,%00010010,%00000111,%10001000
	.db %11000000,%00100001,%00000011,%00000100
	.db %11000000,%00100001,%00000011,%00000100
	.db %11000000,%00110000,%00000111,%10001000
	.db %11000000,%00111001,%00001111,%11110000
	.db %11000000,%00101111,%00000111,%00001000
	.db %11000000,%00100000,%00000111,%00001000
	.db %11100000,%00010000,%00001111,%01010000
	.db %11100000,%00010000,%00001111,%01010000
	.db %11110000,%00001111,%00011111,%11100000
	.db %11110000,%00001000,%00001111,%01010000
	.db %11110000,%00001000,%00000111,%00101000
	.db %11110000,%00001111,%00000111,%11111000

#include "gba.inc"

.end


la routine affiche le sprite dans le frontBuffer. A chaque fois qu'un sprite bouge,
il faut 'rafraichir' l'cran avant (je veux dire par l, restorer la carte depuis le backBuffer
avec gbaResoreMap ou tout simplement effacer l'cran). Je prconise de restorer la carte  chaque
boucle du programme, et aprs redessiner tous les sprites  l'cran un par un.

Attention ! Par dfaut, la routine gbaDrawMaskSprite ne vrifie pas si le sprite est en dehors
de l'cran, ce qui peut provoquer des crash mmoires... Mais pas de panique, il existe une autre
routine, gbaClipSprite  appeler avant gbaDrawMaskSprite, qui s'occupe de a.

Si le sprite est en partie dehors, gbaClipSprite le coupe pour ne garder que la partie visible.
Si le sprite est compltement en dehors, gbaClipSprite renvoie le flag 'carry'.

Exemple :

	; ...

	ld hl,Mario_sprite
	ld de,$021c			; d=2, e=28
	ld bc,$1024			; b=16, c=36
	call gbaClipSprite
	call nc,gbaDrawMaskSprite
	call CR_GRBCopy

	;...
	

Facile, non ?


Il existe de plus une routine appele gbaDrawInvertedSprite, qui affiche un sprite sous le
mme format que prcdement, mais en inversant les valeurs des pixels :
- un pixel blanc est affich noir
- un pixel noir est affich blanc
- un pixel transparent reste transparent

Cela permet de faire des supers effets de clignotage :p (cf Castlevania)

